package org.example.system.dubbo;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.example.api.system.RemoteSystemUserService;
import org.example.common.core.constants.UserConstants;
import org.example.common.core.domain.model.LoginSocial;
import org.example.common.core.domain.model.LoginSocialConfig;
import org.example.common.core.domain.model.LoginUser;
import org.example.common.core.domain.model.RoleDTO;
import org.example.common.core.exception.oauth.UserException;
import org.example.common.datasource.utils.TenantHelper;
import org.example.common.social.config.properties.SocialProperties;
import org.example.system.domain.SysUser;
import org.example.system.domain.vo.SysSocialVo;
import org.example.system.domain.vo.SysUserVo;
import org.example.system.mapper.SysUserMapper;
import org.example.system.service.ISysPermissionService;
import org.example.system.service.ISysSocialService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@DubboService
@RequiredArgsConstructor
public class RemoteSystemUserServiceImpl implements RemoteSystemUserService {

    private final SysUserMapper userMapper;
    private final ISysPermissionService permissionService;
    private final ISysSocialService socialService;
    private final SocialProperties socialProperties;

    @Override
    public LoginUser getSysUserByUsername(String tenantId, String username) {
        return TenantHelper.dynamic(tenantId, () -> {
            SysUser sysUser = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                    .select(SysUser::getUserName, SysUser::getStatus)
                    .eq(SysUser::getUserName, username));
            if (ObjectUtil.isNull(sysUser)) {
                throw new UserException("user.not.exists", username);
            }
            if (UserConstants.USER_DISABLE.equals(sysUser.getStatus())) {
                throw new UserException("user.blocked", username);
            }
            // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可
            // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
            return buildLoginUser(userMapper.selectUserByUserName(username));
        });
    }

    @Override
    public LoginUser getSysUserByPhone(String tenantId, String phone) {
        return TenantHelper.dynamic(tenantId, () -> {
            SysUser sysUser = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                    .select(SysUser::getUserName, SysUser::getStatus)
                    .eq(SysUser::getPhonenumber, phone));
            if (ObjectUtil.isNull(sysUser)) {
                throw new UserException("user.not.exists", phone);
            }
            if (UserConstants.USER_DISABLE.equals(sysUser.getStatus())) {
                throw new UserException("user.blocked", phone);
            }
            // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可
            // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
            return buildLoginUser(userMapper.selectUserByPhonenumber(phone));
        });
    }

    @Override
    public LoginUser getSysUserByEmail(String tenantId, String email) {
        return TenantHelper.dynamic(tenantId, () -> {
            SysUser sysUser = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                    .select(SysUser::getUserName, SysUser::getStatus)
                    .eq(SysUser::getEmail, email));
            if (ObjectUtil.isNull(sysUser)) {
                throw new UserException("user.not.exists", email);
            }
            if (UserConstants.USER_DISABLE.equals(sysUser.getStatus())) {
                throw new UserException("user.blocked", email);
            }
            // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可
            // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
            return buildLoginUser(userMapper.selectUserByEmail(email));
        });
    }

    @Override
    public LoginUser getSysUserByUserId(String tenantId, Long userId) {
        return TenantHelper.dynamic(tenantId, () -> {
            SysUser sysUser = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
                    .select(SysUser::getUserName, SysUser::getStatus)
                    .eq(SysUser::getUserId, userId));
            if (ObjectUtil.isNull(sysUser)) {
                throw new UserException("user.not.exists", "");
            }
            if (UserConstants.USER_DISABLE.equals(sysUser.getStatus())) {
                throw new UserException("user.blocked", sysUser.getUserName());
            }
            // 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可
            // 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
            return buildLoginUser(userMapper.selectUserByUserName(sysUser.getUserName()));
        });
    }

    @Override
    public LoginSocial getSocialByAuthId(String tenantId, String authId) {
        return TenantHelper.dynamic(tenantId, () -> {
            List<SysSocialVo> list=   socialService.selectByAuthId(authId);
            if(CollectionUtils.isEmpty(list)) return null;
            SysSocialVo sysSocialVo=list.get(0);
            LoginSocial loginSocial=new LoginSocial();
            BeanUtils.copyProperties(sysSocialVo,loginSocial);
            return loginSocial;
        });
    }

    @Override
    public Map<String, LoginSocialConfig> getLoginSocialConfig(String tenantId) {
        Map<String, LoginSocialConfig> result=new HashMap<>();
        socialProperties.getType().forEach((k,v)->{
            LoginSocialConfig loginSocialConfig=new LoginSocialConfig();
            BeanUtils.copyProperties(v,loginSocialConfig);
            result.put(k,loginSocialConfig);
        });
        return result;
    }



    /**
     * 构建登录用户
     */
    private LoginUser buildLoginUser(SysUserVo userVo) {
        LoginUser loginUser = new LoginUser();
        loginUser.setTenantId(userVo.getTenantId());
        loginUser.setUserId(userVo.getUserId());
        loginUser.setDeptId(userVo.getDeptId());
        loginUser.setUsername(userVo.getUserName());
        loginUser.setNickname(userVo.getNickName());
        loginUser.setPassword(userVo.getPassword());
        loginUser.setUserType(userVo.getUserType());
        loginUser.setAuthorizes(permissionService.getMenuPermission(userVo.getUserId()));
        loginUser.setRoles(permissionService.getRolePermission(userVo.getUserId()));
        loginUser.setDeptName(ObjectUtil.isNull(userVo.getDept()) ? "" : userVo.getDept().getDeptName());
        List<RoleDTO> roles = BeanUtil.copyToList(userVo.getRoles(), RoleDTO.class);
        loginUser.setDtoCollection(roles);
        return loginUser;
    }

}
